package com.ruoyi.web.controller.business.order.factory;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.business.base.PageParam;
import com.ruoyi.business.customer.domain.JbCustomer;
import com.ruoyi.business.customer.service.JbCustomerService;
import com.ruoyi.business.order.domain.JbPaymentReceived;
import com.ruoyi.business.order.domain.vo.JbPaymentReceivedVO;
import com.ruoyi.business.order.service.JbPaymentReceivedService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.web.controller.business.order.vo.JbAuditStatusEnum;
import com.ruoyi.web.controller.business.order.vo.JbOrderVO;
import com.ruoyi.web.controller.flyflow.factory.FlyFlowFactory;
import com.ruoyi.web.controller.flyflow.util.FlyFlowUtil;
import com.ruoyi.web.controller.system.factory.SysUserFactory;
import com.ruoyi.web.controller.tool.JoCodeUtils;
import com.ruoyi.web.core.JoController;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Arrays;
import java.util.Date;
import java.util.StringJoiner;

/**
 * 业务 退款工厂
 *
 * @author Jyl
 */
@Log4j2
@Component
public class JbPaymentReceivedFactory extends JoController
{

    @Getter
    @Autowired
    private JbPaymentReceivedService service;
    @Autowired
    private JbApprovalLogFactory jbApprovalLogFactory;
    @Autowired
    private FlyFlowFactory factory;
    @Autowired
    private JbCustomerService jbCustomerService;
    @Autowired
    private JbOrderFactory jbOrderFactory;
    @Autowired
    private SysUserFactory sysUserFactory;

    /**
     * 查询回款列表
     *
     * @param page
     * @param jbPaymentReceivedVO
     * @return
     */
    public IPage<JbPaymentReceivedVO> list(PageParam page, JbPaymentReceivedVO jbPaymentReceivedVO)
    {
        return service.pageList(page, jbPaymentReceivedVO);
    }

    /**
     * 获取回款详细信息
     */
    public JSONObject getById(Long id)
    {
        JbPaymentReceived jbPaymentReceived = service.getById(id);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(jbPaymentReceived));

        //根据订单号查询业务经理
        String order = jbPaymentReceived.getRelatedOrder();
        if (StrUtil.isNotEmpty(order))
        {
            JbOrderVO jbOrderVO = jbOrderFactory.getInfoByNumber(order);
            jsonObject.put("businessManager", ObjectUtil.isNotEmpty(jbOrderVO) ? jbOrderVO.getBusinessManager() : "");
        }

        //提交人昵称
        SysUser user = sysUserFactory.getSysUser(jbPaymentReceived.getCreateBy());
        if (ObjectUtil.isNotEmpty(user))
        {
            jsonObject.put("createName", user.getNickName());
        }

        //通知人员名称
        String userIds = jbPaymentReceived.getNotifiedEmployeeId();
        if (StrUtil.isEmpty(userIds))
        {
            return jsonObject;
        }
        for (String s : userIds.split(","))
        {
            user = sysUserFactory.getSysUser(Long.valueOf(s));
            StringJoiner sb = new StringJoiner(",");
            if (ObjectUtil.isNotEmpty(user))
            {
                sb.add(user.getNickName());
            }
            jsonObject.put("notifiedEmployeeName", sb.toString());
        }

        return jsonObject;
    }

    /**
     * 新增
     *
     * @param jbPaymentReceived 回款VO
     * @return
     */
    @Transactional
    public boolean add(JbPaymentReceived jbPaymentReceived)
    {
        JbCustomer jbCustomer = jbCustomerService.getById(jbPaymentReceived.getCustomerId());
        jbPaymentReceived.setCustomerName(jbCustomer.getCustomerName());
        jbPaymentReceived.setPaymentNumber(JoCodeUtils.CODE().PAYMENTRECEIVED);
        jbPaymentReceived.setSubmissionTime(new Date());
        jbPaymentReceived.setStatus(JbAuditStatusEnum.task1.getKey());

        service.save(jbPaymentReceived);
        startProcess(jbPaymentReceived);
        return true;
    }

    /**
     * @param processNumber 流程编码
     * @param id            订单主键
     */
    public void updateProcessNumber(String processNumber, Long id)
    {
        service.update(new LambdaUpdateWrapper<JbPaymentReceived>()
                .eq(JbPaymentReceived::getId, id)
                .set(JbPaymentReceived::getProcessNumber, processNumber));
    }

    /**
     * @param processNumber 流程编号
     * @return 回款对象
     */
    public JbPaymentReceived getInfoByProcessNumber(String processNumber)
    {
        return service.getOne(new LambdaQueryWrapper<JbPaymentReceived>()
                .eq(JbPaymentReceived::getProcessNumber, processNumber));
    }

    /**
     * @param number 业务编号
     * @return 回款对象
     */
    public JbPaymentReceived getInfo(String number)
    {
        return service.getOne(new LambdaQueryWrapper<JbPaymentReceived>()
                .eq(JbPaymentReceived::getPaymentNumber, number));
    }

    /**
     * 启动流程实例
     *
     * @param jbPaymentReceived
     */
    @Transactional
    public void startProcess(JbPaymentReceived jbPaymentReceived)
    {
        //处理业务对象
        JSONObject order = JSONObject.parseObject(JSONObject.toJSONString(jbPaymentReceived));
        //获取流程
        JSONObject flow = FlyFlowUtil.getProcessInstance(factory.getProcessInstance(), "回款审批");
        //获取启动表单
        JSONObject flowInfo = factory.getProcessInstanceInfo(flow.getString("flowId"));

        //构建启动对象
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("uniqueId", flow.getString("uniqueId"));
        jsonObject.put("flowId", flow.getString("flowId"));
        jsonObject.put("paramMap", FlyFlowUtil.buildParamMap(flowInfo, order));
        JSONObject re = factory.processInstanceStart(jsonObject);
        if (!re.getBoolean("ok")) throw new RuntimeException("payment_received process start fail");

        updateProcessNumber(re.getString("data"), jbPaymentReceived.getId());
        jbApprovalLogFactory.saveApprovalLog(
                "payment_received",
                jbPaymentReceived.getPaymentNumber(),
                re.getString("data"),
                "发起审批",
                "提交回款审批",
                "提交成功"
        );
    }

    /**
     * 编辑
     *
     * @param jbPaymentReceived 退款vo
     * @return
     */
    @Transactional
    public boolean edit(JbPaymentReceived jbPaymentReceived)
    {
        JbCustomer jbCustomer = jbCustomerService.getById(jbPaymentReceived.getCustomerId());
        jbPaymentReceived.setCustomerName(jbCustomer.getCustomerName());

        service.updateById(jbPaymentReceived);
        return true;
    }

    /**
     * 删除回款
     */
    public boolean remove(@PathVariable Long[] ids)
    {
        return service.removeByIds(Arrays.asList(ids));
    }

    /**
     * 更新 业务状态
     *
     * @param id     业务主键
     * @param status 业务状态
     * @return 执行结果
     */
    public Boolean updataBusinessStatus(Long id, String status)
    {
        return service.update(new LambdaUpdateWrapper<JbPaymentReceived>()
                .eq(JbPaymentReceived::getId, id)
                .set(JbPaymentReceived::getStatus, status)
        );
    }
}
